- /* sxfxsdiv.cpp by K.Tsuru */
- // function ID = 510 BRADIX
- /*****************************************************
- SDecimal class
- Provides the division of SDecimal by a short integer.
- result = m/x, x <= ULONG_MAX/BRADIX
- ******************************************************/
- #ifndef SN_H
- #include "sn.h"
- #endif
- static const char* func = "XsDiv";
- void XsDiv(const SDecimal& m, ulong x, SDecimal& result){
- if(x > m.SlOpMaxValue()) m.SetError(m.OUT_OF_RANGE, func, 510);
- if(!x) m.SetError(m.DIVIDED_BY_ZERO, func, 510);
- if(!m.Sign()){ result.SetZero(); return; }
- if(x == 1){
- result = m; return;
- }
- if( result.figure.size() != m.figure.size() ) m.SetError(m.SYNTAX_ERR, func, 510);
- uint i, rsz = result.Size();
- /*
- Considering the case &m == &result pay attention to not destroy the content of "m"
- via "result".
- For the fast access to figure[] do it via the first address of "elements".In the
- calculation of pi in 65,528 figures it is 40% faster than the "result.figure[]"
- version.
- */
- fType* rv = result.figure.Elements();
- const fType* mv = m.ReadFigures();
- #ifndef NDEBUG
- result.figure[rsz-1]; m.figure(rsz-1);
- #endif
- //When the figures of "m" is small it maybe get a factor by a few aditional figures.
- //For example 1/256.
- uint rt = m.aTail, rh = rsz -1, k = min(m.aHead + 4u, rsz);
- #ifndef NDEBUG
- result.figure[k-1]; m.figure(k-1);
- #endif
- ulong t = 0;
- #if 1 // mv[] version
- for( i = rt; i < k; i++) {
- t = (t << BRADIX_BITS) + mv[i];
- //Because mv[i] < BRADIX this statement can be replaced by
- //"t = (t << BRADIX_BITS) | mv[i];" but the speed is the same.
- rv[i] = fType(t/x);
- t = t - rv[i]*x; //This is faster than t = t%x;.
- }
- #else // *mv version Its speed is the same as mv[] version.
- //It would be optimized mv[] ---> *mv by Turbo C++.
- mv += rt; rv += rt;
- for( i = rt; i < k; i++) {
- t = (t << BRADIX_BITS) + *mv;
- *rv = fType(t/x);
- t = t - (*rv)*x;
- mv++; rv++;
- }
- rv = result.figure.Elements(); mv = m.ReadFigures();
- #endif
- if(t){//Maybe infinite decimal. mv[i] = 0 <-- This avoids the overhead caused by reading mv[].
- for( ; i < rsz; i++){ //Because it is a rare case that the remainder becomes zero,
- //it does not add the condition t == 0.
- t = (t << BRADIX_BITS);
- rv[i] = fType(t/x);
- t = t - rv[i]*x;
- }
- rh = rsz -1;
- //The residual part is filled by zeros.
- } else if(result.aHead >= i){ //finite decimal
- result.figure.clear(i); rh = i-1;
- }
- if(result.aTail < rt) result.figure.clear(result.aTail, rt-1);
- //Ut check the figure positions.
- while( (rt < rsz) && !rv[rt]) rt++; //The figures decreases?
-
- if( (rt == rsz) && !rv[rt-1] ){ //It becomes zero.
- result.aTail = result.aHead = 0; result.SetSign(0);
- } else { //Almost the lowest figure is not zero.
- result.aTail = rt;
- k = rh;
- while(k && !rv[k]) k--;
- result.aHead = k;
- result.SetSign(m.Sign());
- }
- }
sxfxsdiv.cpp : last modifiled at 2017/03/13 14:32:02(2,932 bytes)
created at 2015/12/22 16:09:56
The creation time of this html file is 2017/10/27 15:45:59 (Fri Oct 27 15:45:59 2017).